﻿using FreeSql.Internal.Model;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Reflection;
using System.Text.Json.Nodes;
using Wen.Core.Helps;
using Wen.Models.Attributes;
using Wen.Models.Entity;

namespace WebServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class DbController(IFreeSql freeSql) : Controller
    {
        [HttpPost]
        [Route("select")]
        public IActionResult GetSelect(object select, string typeName)
        {
            var type = Type.GetType(typeName);
            //var val = Convert.ChangeType(select, type);
            var result = freeSql.Select<object>().AsType(type).ToList();
            return Json(result);
        }

        [HttpPost]
        [Route("select-object")]
        public IActionResult PostSelectObject([FromBody] SelectObjectRequest request)
        {
            try
            {
                var typeName = request.typeName;
                var isIdDesc = request.isIdDesc;
                var value = request.value;
                var pageNumber = request.pageNumber;
                var pageSize = request.pageSize;

                var itemType = Type.GetType(typeName) ?? throw new ArgumentNullException(nameof(typeName), "类型不能为空");

                var select = freeSql.Select<object>().AsType(itemType);

                if (!string.IsNullOrEmpty(value))
                {
                    var fi = new DynamicFilterInfo() { Filters = [], Logic = DynamicFilterLogic.Or };

                    foreach (var prop in itemType.GetProperties())
                    {
                        if (prop.GetCustomAttribute<ColAttribute>() is ColAttribute { IsFilter: true })
                        {
                            var sub = new DynamicFilterInfo()
                            {
                                Field = prop.Name,
                                Value = value,
                                Operator = DynamicFilterOperator.Contains,
                            };
                            fi.Filters.Add(sub);
                        }
                    }
                    select.WhereDynamicFilter(fi);
                }

                if ((typeof(IEntityBase).IsAssignableFrom(itemType)
                    || itemType.GetProperty("ID", BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase) != null)
                    && isIdDesc)
                {
                    select.OrderByPropertyName("ID", false);
                }
                var count = select.Count();
                var data = select.Page(pageNumber, pageSize).ToList();

                return Json(new { success = true, data, pageNumber, pageSize, count });
            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });
            }
        }

        public class SelectObjectRequest
        {
            /// <summary>
            /// 类型名称
            /// </summary>
            public string typeName { get; set; }
            /// <summary>
            /// 是否降序
            /// </summary>
            public bool isIdDesc { get; set; }
            /// <summary>
            /// 筛选值
            /// </summary>
            public string? value { get; set; }
            /// <summary>
            /// 总数
            /// </summary>
            public long count { get; set; }
            /// <summary>
            /// 分页页码
            /// </summary>
            public int pageNumber { get; set; } = 1;
            /// <summary>
            /// 分页大小
            /// </summary>
            public int pageSize { get; set; } = 10;
        }

        /// <summary>
        /// 更新对象
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        [HttpPost]
        [Route("update-object")]
        public IActionResult PostUpdateObject([FromBody] ObjectRequest request)
        {
            try
            {
                var item = GetItemObject(request);
                var res = freeSql.Update<object>().AsType(item.itemType).SetSource(item.item).ExecuteAffrows();

                return Json(new { success = res > 0, message = res > 0 ? "更新成功" : "更新失败" });
            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });
            }
        }
        /// <summary>
        /// 插入对象
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("insert-object")]
        public IActionResult PostInsertObject([FromBody] ObjectRequest request)
        {
            try
            {
                var item = GetItemObject(request);
                var res = freeSql.Insert<object>().AsType(item.itemType).AppendData(item.item).ExecuteAffrows();
                return Json(new { success = res > 0, message = res > 0 ? "插入成功" : "插入失败" });
            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });
            }
        }

        //删除数据
        [HttpPost]
        [Route("delete-object")]
        public IActionResult PostDeleteObject([FromBody] ObjectRequest request)
        {
            try
            {
                var item = GetItemObject(request);
                var res = freeSql.Delete<object>().AsType(item.itemType).Where(item.item).ExecuteAffrows();
                return Json(new { success = res > 0, message = res > 0 ? "删除成功" : "删除失败" });
            }
            catch (Exception ex)
            {
                return Json(new { success = false, message = ex.Message });

            }
        }

        private (object item, Type itemType) GetItemObject(ObjectRequest request)
        {
            var itemType = Type.GetType(request.typeName) ?? throw new Exception("类型不能为空");
            var itemValue = System.Text.Json.JsonSerializer.Deserialize(request.value, itemType, SourceGenerationContext.Default)
                ?? throw new Exception("对象不能为空");
            return (itemValue, itemType);
        }


        public class ObjectRequest
        {
            /// <summary>
            /// 类型名称
            /// </summary>
            public string typeName { get; set; }
            /// <summary>
            /// 更新对象
            /// </summary>
            public JsonNode value { get; set; }
        }
    }
}
